package com.maowei.event;

import com.alibaba.otter.canal.protocol.CanalEntry;
import com.maowei.common.CanalConstants;
import com.maowei.util.SpringContextUtils;

import java.util.HashMap;
import java.util.Map;

/**
 * 事件处理 工厂
 *
 * @author maowei
 * @date 2020/9/7
 */
public class EventHandlerFactory {

    private Map<String, IEventHandler> handlerMap = new HashMap<>();

    public IEventHandler getHandler(String key) {
        return handlerMap.get(key);
    }

    public void setHandler(String key, IEventHandler iEventHandler) {
        handlerMap.put(key, iEventHandler);
    }

    public static String createUnionKey(TableInfo tableInfo, CanalEntry.EventType eventType) {
        return createUnionKey(tableInfo.getSchemaName(), tableInfo.getTableName(), eventType);
    }

    public static String createUnionKey(String schemaName, String tableName, CanalEntry.EventType eventType) {
        return schemaName + "-" + tableName + "-" + eventType.getValueDescriptor().getName();
    }

    /**
     * 统一的处理器
     */
    public static String createUnionKey(CanalEntry.EventType eventType) {
        return createUnionKey(CanalConstants.UNITY_SCHEMA, CanalConstants.UNITY_TABLE, eventType);
    }

    /**
     * 自动注册到工厂容器中(spring容器启动完成时调用触发)
     */
    public void autoRegister() {
        Map<String, AbstractEventHandler> eventHandlerMap = SpringContextUtils.getBeansByType(AbstractEventHandler.class);
        for (Map.Entry<String, AbstractEventHandler> eventHandlerEntry : eventHandlerMap.entrySet()) {
            AbstractEventHandler eventHandler = eventHandlerEntry.getValue();
            Class<? extends AbstractEventHandler> eventHandlerClass = eventHandler.getClass();
            TableEvent annotation = eventHandlerClass.getAnnotation(TableEvent.class);
            if (annotation != null) {
                CanalEntry.EventType[] eventTypes = annotation.eventTypes();
                for (CanalEntry.EventType eventType : eventTypes) {
                    setHandler(createUnionKey(annotation.schemaName(), annotation.tableName(), eventType), eventHandler);
                }
            }
        }
    }
}
